home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 3 / Cream of the Crop 3.iso / comm / dep309.zip / DEPARC.EXE / SCRIPTS.EXE / FILEPICK.DSL < prev    next >
Text File  |  1993-10-15  |  11KB  |  288 lines

  1. (*   FilePick.DSL script  V.1.1  by Michael Spalter July 1992   
  2.  
  3.     This script mostly consists of a pair of user defined 
  4.     functions which provide the user with a file picklist.
  5.     The user can also move around the directory structure by
  6.     selecting parent and sub-directories.
  7.  
  8.     This script should be considered as an excellent example
  9.     of a DSL program, especially with regard to screen
  10.     management, string handling and mathematical calculations. 
  11.     The script contains all major constuctions supported by 
  12.     DSL and a good selection of DSL functions and procedures.
  13.  
  14.     There are two shortcomings of this script program, in
  15.     order to keep it simpler than it might be otherwise.
  16.     Ideally, all subdirectories would be in the list of
  17.     files, regardless of the wildcard; as it stands, 
  18.     subdirectories are only shown if the directory matches
  19.     the wildcard, (e.g. *.* or *.). Secondly, this file
  20.     picker does not support scrolling so if a directory has
  21.     more than 80 files, on the first 80 are shown.  Users
  22.     may wish to add these features themselves as en exercise.
  23.     Also, users who are fairly proficient in DSL will also 
  24.     spot several areas in which this script could be made to
  25.     run more efficiently, including some major changes to 
  26.     the way it works. If we optimised this script, it would
  27.     be very difficult to comprehend for many users so we submit
  28.     it as it is as a working example. Deleting the comments
  29.     throughout this file will make it substantially shorter,
  30.     but please leave the comments in if you intend redistributing
  31.     the file as it is most useful to others that way.
  32.  
  33.     ASKFILENAME is the main function which does most of the
  34.     work; GETNAME is used by ASKFILENAME. The main body
  35.     of the script consists of only nine lines, which you will
  36.     find right at the bottom. It simply calls the ASKFILENAME
  37.     function and then loads the file selected into Deputy's
  38.     built in text editor. This is a somewhat trivial example, 
  39.     and no doubt you will have better uses for these functions. *)
  40.  
  41.  
  42. Script FilePick;    (* This is the start of the script *)
  43.  
  44. (* There are only two variables used by the main script, 
  45.    which must always be defined here at the start. 'SELECTED'    
  46.    is the string used to store the filename eventually selected.
  47.    'USERSPEC' is the wildcard or filespec which the user enters  *)
  48.  
  49. VAR Selected : STRING[30];   (* It may include a path, hence the length *)
  50.     UserSpec : STRING[30];
  51.  
  52. (* Now we go straight into defining our own functions.      
  53.    The GETNAME function takes two arguments: an integer and
  54.    a string. The function returns a filename corresponding 
  55.    to the position in the directory specified by the integer
  56.    argument. The string contains a wildcard or 'filespec'
  57.    which the file should match, for example '*.*' or '*.txt'  
  58.  
  59.    Note that the first thing we do is define the variable 
  60.    which we use in the function. These are specific to
  61.    this function only and may not be shared by any other
  62.    function or procedure.                                      *)
  63.  
  64. FUNCTION GetName(Position : INTEGER; Wildcard : STRING) : STRING;
  65. VAR
  66. Filename : STRING[12];   Attrib : INTEGER;  
  67. Found : BOOLEAN;         Round : INTEGER;
  68. BEGIN
  69. Found := DirFirst(Wildcard,16,Filename,Attrib);
  70.    IF Position>1 THEN 
  71.      For Round := 1 TO (Position-1) DO
  72.      Found:=DirNext(Filename,Attrib);
  73.      END; 
  74.    END;
  75.    IF (Attrib AND 16)=16 THEN   (*  Is it a directory ?  If so,    *)
  76.    Filename:='['+Filename+']';  (*  enclose it in square brackets  *)
  77.    END;
  78. Return(Filename);
  79. END GetName;
  80.  
  81. (* And now we define the large function 'ASKFILENAME' *)
  82.  
  83. FUNCTION AskFilename(Wildcard : STRING) : STRING;
  84. VAR
  85. Filename : STRING[12];  CurName: STRING[12];  
  86. Found : BOOLEAN;        Whandle : INTEGER;      
  87. Attrib : INTEGER;       Count : INTEGER;       
  88. Round : INTEGER;        Current : INTEGER;    
  89. Key : INTEGER;          Next : INTEGER;
  90. Line : INTEGER;         Row : INTEGER;
  91. Xoffset : INTEGER;      Yoffset : INTEGER;      
  92. WinWidth : INTEGER;     Winheight : INTEGER;
  93. ReDisplay : BOOLEAN;    OrigDir : STRING[30];
  94. NewName : STRING[30];   XRound : INTEGER;
  95.  
  96. BEGIN
  97. ReDisplay:=TRUE;  
  98. OrigDir:=CurrentDir;
  99. Escape(FALSE);  
  100. Key:=0; Round:=0; 
  101. Cursor(FALSE);  ClrScr;
  102.  
  103. (* First we test whether the submitted wildcard is a plain
  104.    path name, without any wildcard. We use the ChDir
  105.    function which returns TRUE if the directory change was 
  106.    successful. There is also allowance for the user entering
  107.    just a drive name, such as 'C:'. If this section determines
  108.    that it is just a directory, then the wildcard defaults to
  109.    *.* in that directory.                                           *)
  110.  
  111.   Found:=ChDir(Wildcard);
  112.   IF Found OR ((Slice(Wildcard,1,1)=":") AND (Length(Wildcard)=2)) THEN
  113.   Chdir(Wildcard);
  114.   WildCard:='*.*';
  115.   END;
  116.  
  117.   (* If it wasn't a plain path it must either be a 
  118.      combined path and wildcard or just a wildcard.
  119.      This function has to be fairly robust in that
  120.      a user can potentially enter any combination of 
  121.      drive, path and filename wildcard.                  
  122.  
  123.      Now we check if the wildcard contain a '\'
  124.      character - if it does, then we can assume that
  125.      it contains a pathname. So we now run through
  126.      the string, character by character, continuously
  127.      searching for a valid path. Once we get to the end of 
  128.      the string, we separate the last valid path found from 
  129.      anything which followed it. Anything which followed
  130.      it is assumed to be a filename wildcard.                  *)
  131.  
  132.   IF ( POS(Wildcard,'\')<>-1 ) THEN
  133.   Round:=1; 
  134.      REPEAT
  135.      Found:=ChDir(Slice(Wildcard,0,Round));
  136.      IF Found THEN Count:=Round; END;
  137.      INC(Round);
  138.      UNTIL Round=Length(Wildcard);
  139.   WildCard:=Slice(Wildcard,Count,(Length(Wildcard)-Count)); 
  140.   END;
  141.  
  142.    (* Now we check for any drive designations which are 
  143.       redundant as they were taken care of earlier. If
  144.       we find anything like 'C:' we chop it off.           *)
  145.  
  146.      IF Slice(Wildcard,1,1)=':' THEN 
  147.      WildCard:=Slice(Wildcard,2,(Length(Wildcard)-2));
  148.      END;  
  149.  
  150.    (* And finally we chop off any leading '\' characters   *)
  151.  
  152.      IF  Slice(Wildcard,0,1)='\' THEN
  153.      Wildcard:= Slice(Wildcard,1,(Length(Wildcard)-1)); 
  154.      END;
  155.           
  156.   (* This next section is the continous loop which
  157.      only exits once a file has been selected.     *)
  158.  
  159.   While ReDisplay AND (Key<>27) DO
  160.  
  161.   (* First we count the number of files in the 
  162.      directory which match the wildcard.       *)
  163.  
  164.   Found:=DirFirst(Wildcard,16,Filename,Attrib);
  165.   IF Filename='' THEN ChDir(OrigDir); RETURN(''); END; 
  166.   Count:=1; Key:=0;
  167.      WHILE Found AND (COUNT<81) DO                     
  168.      Found:=DirNext(Filename,Attrib); 
  169.      INC(count);                            
  170.      END;                             
  171.      DEC(Count);                      
  172.      IF Count<4 THEN 
  173.      WinWidth:=(Count*15); 
  174.      ELSE WinWidth:=60; 
  175.      END;
  176.   IF Count>80 THEN Count:=80; END;
  177.  
  178. (* Now, using that information, we calculate the size
  179.    of window required. This program is currently limited
  180.    to 80 files as it does not support scrolling   *)
  181.  
  182.   WinHeight:=(((COUNT+1) DIV 4)+2);
  183.     IF (COUNT MOD 4)=0 THEN DEC(WinHeight); END;
  184.     IF Winheight>21 THEN WinHeight:=21; END;
  185.     IF Slice(CurrentDir,Length(CurrentDir)-1,1)<>'\' THEN
  186.     CurName:='\';  ELSE CurName:='';   END;
  187.   Whandle := Window(5,2,WinWidth,WinHeight,
  188.      (' '+CurrentDir+CurName+Wildcard+' '),27);
  189.   UseWindow(Whandle); 
  190.  
  191.   (*  Now that we've drawn the window and selected it,
  192.       we can display all of the filenames:   *)
  193.  
  194.   Found:=DirFirst(Wildcard,16,Filename,Attrib);
  195.   Count:=1;
  196.      WHILE (Found AND (Count<81)) DO
  197.      Row:=((((Count-1) MOD 4)*15)+1);
  198.      Line:=((Count-1) DIV 4);  
  199.           IF (Attrib AND 16)=16 THEN Filename:='['+Filename+']'; END;
  200.      GoToXY(Row,Line); Write(Filename);
  201.      Found:=DirNext(Filename,Attrib);
  202.      INC(count);
  203.      END;
  204.  
  205.   DEC(count);
  206.   Current := 1;
  207.   While Keypressed DO Rdkey; END;  (* This clears the keyboard buffer *)
  208.  
  209.   (* Now we start the loop which moves the highlight bar
  210.      around the screen. This loop only exits when the  user
  211.      presses <ENTER> to select a file/dir or presses ESCAPE.  *)
  212.  
  213.     Cursor(FALSE);
  214.     While (Key<>13) AND (Key<>27) DO
  215.     Line:=((Current-1) DIV 4);  
  216.     Row:=((((Current-1) MOD 4)*15)+1);
  217.     CurName:=GetName(Current,Wildcard);
  218.        REPEAT             
  219.        BackGnd(Red); ForeGnd(Yellow);      (* This re-writes the current  *)
  220.        GoToXY(Row,Line); Write(CurName);   (* filename in highlighed text *)
  221.        REPEAT UNTIL KeyPressed;    
  222.        Key:=RdKey;
  223.          Case Key OF
  224.          328: Next:=Current-4; |    (* UP    *)
  225.          336: Next:=Current+4; |    (* DOWN  *)
  226.          331: Next:=Current-1; |    (* LEFT  *)
  227.          333: Next:=Current+1; |    (* RIGHT *)
  228.          END;
  229.      BackGnd(Blue); ForeGnd(LCyan);        
  230.      GoToXY(Row,Line); Write(CurName);          (* Re-write in normal text *)
  231.          IF  (Next<1) OR (Next>Count) THEN Next:=Current; END;
  232.        UNTIL (Next<>Current) OR (Key=13) OR (Key=27);
  233.  
  234.    (* This point is only reached once the user has selected something *)
  235.  
  236.      Current:=Next; ReDisplay:=False;
  237.  
  238.      (* Now, we test if the selection is a directory and 
  239.         if it is, we change to that directory and then
  240.         set a special flag 'ReDisplay' to tell the script that
  241.         the directory needs redrawing  *)
  242.  
  243.         IF (Slice(CurName,0,1)='[') THEN 
  244.        
  245.         ReDisplay:=TRUE;
  246.         END;
  247.      END;
  248.  
  249.   (* This point is only reached once either another directory
  250.      has been selected, a file has been selected or ESCAPE has
  251.      been pressed.                                               *)
  252.      
  253.      ChDir(Slice(CurName,1,(LENGTH(Curname)-2))) ;   
  254.      CloseWindow(Whandle);
  255.   END;   
  256.  
  257.    (* This point is only reached if a new dir was NOT selected  *)
  258.  
  259.    Cursor(TRUE);
  260.    IF Key=27 THEN      (* Did the user press ESCAPE ?  *)
  261.    NewName:=''; ELSE
  262.    IF Slice(CurrentDir,Length(CurrentDir)-1,1)<>'\' THEN 
  263.    CurName:='\' ELSE CurName:=''; END;  
  264.    NewName:=CurrentDir+CurName+GetName(Current,Wildcard); 
  265.  
  266.    END;
  267. BackGnd(Black); ForeGnd(White); GotoXY(0,WhereY); 
  268. ChDir(OrigDir);   (* Change back to the original directory *)
  269. Return(NewName);  (* And restore all colours to normal  *)
  270. END AskFilename;
  271.  
  272. BEGIN              (*    Main Program body starts here 
  273.                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^      *)
  274.  
  275. ClrScr;
  276. Write('Please enter a filespec [*.*]: ');
  277. Read(UserSpec);
  278. Selected:=AskFilename(UserSpec);  
  279.   IF Selected='' THEN 
  280.   Write('You did not select any file !\n\r');
  281.     ELSE  
  282.     Write('You selected the file :');
  283.     WrStr(Selected);
  284.   END; 
  285. WrLn; WrLn;
  286. Cursor(TRUE);
  287. END FilePick.
  288.